use tower::{ServiceBuilder, Service, ServiceExt, BoxError, Layer};
use std::task::{Context, Poll};
use std::future::Future;
use std::error::Error;
use std::pin::Pin;
use std::sync::Arc;
use std::ops::Deref;
use futures::channel::mpsc;
use futures::StreamExt;
use tower::util::Oneshot;
use std::marker::PhantomData;
use tower::limit::concurrency::future::ResponseFuture;

pub struct Entity{
    name:String,
}
impl Entity {
    pub fn new(s:impl ToString) ->Self{
        let name = s.to_string();
        Self{name }
    }
    pub async fn get_name(&self,cmd:String)->String{
        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
        match cmd.as_str() {
            "" | "name" => self.name.clone(),
            _=> "default".to_string(),
        }
    }
}
pub struct HandlerInterface<T>{
    inner:Arc<T>,
}
impl<T> HandlerInterface<T>{
    pub fn new(inner:T)->Self{
        let inner = Arc::new(inner);
        Self{inner}
    }
}
impl Clone for HandlerInterface<Entity>{
    fn clone(&self) -> Self {
        Self{inner:self.inner.clone()}
    }
}
impl Service<String> for HandlerInterface<Entity>{
    type Response = String;
    type Error = BoxError;
    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>+Send>>;

    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        Poll::Ready(Ok(()))
    }
    fn call(& mut self, req: String) -> Self::Future {
        let entity = self.inner.clone();
        Box::pin(async move{
            Ok(entity.get_name(req).await)
        })
    }
}

pub struct Handle<T,Request>
    where T:Service<Request>
{
    service:T,
    _p : PhantomData<Request>,
}
impl <T,Request> Handle<T,Request>
    where T:Service<Request>
{
    async fn async_task(&mut self, r:Request)->Result<T::Future,T::Error>  {
            let ready =  self.service.ready().await;
            match ready {
                Ok(o)=>{
                    Ok(o.call(r))
                }
                Err(e)=>{
                    Err(e)
                }
        }
    }
}
async fn handle(request: &'static str) -> Result<&'static str, BoxError> {
   Ok(request)
}
#[tokio::main]
async fn main() {
    let entity = Entity::new("hello world");
    let handle = HandlerInterface::new(entity);
    let service = ServiceBuilder::new()
        .timeout(std::time::Duration::from_secs(1))
        .concurrency_limit(1)
        // .buffer(1024)
        .service(handle);
    let mut handle = Handle{service,_p:PhantomData::default()};
    for i in 0..10 {
        let svc = handle.async_task("foo".to_string()).await;
        match svc {
            Ok(task) => {
                tokio::spawn(async move {
                    let response = task.await.unwrap_or_else(|e|{e.to_string()});
                    wd_log::log_debug_ln!("index:{},response:{}",i,response)
                });
            }
            Err(e) => {
                wd_log::log_error_ln!("任务执行错误：{}",e.to_string())
            }
        }

    }
    tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
}